home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / basic / qbnws104.zip / QBNWS104.NWS < prev    next >
Text File  |  1990-09-03  |  83KB  |  1,808 lines

  1.      Volume  1, Number  4                                September  3, 1990
  2.  
  3.      
  4.      
  5.      
  6.      
  7.      
  8.      
  9.      
  10.      
  11.      
  12.      
  13.      
  14.                    **************************************************
  15.                    *                                                *
  16.                    *                    QBNews                      *
  17.                    *                                                *
  18.                    *      International QuickBASIC Electronic       *
  19.                    *                  Newsleter                     *
  20.                    *                                                *
  21.                    *    Dedicated to promoting QuickBASIC around    *
  22.                    *                  the world                     *
  23.                    *                                                *
  24.                    **************************************************
  25.      
  26.      
  27.      
  28.      
  29.      
  30.      
  31.      
  32.      
  33.      
  34.      
  35.      
  36.      
  37.      
  38.      
  39.      
  40.      
  41.         The  QBNews  is  an electronic newsletter  published  by  Clearware
  42.      Computing. It can be freely distributed providing NO CHARGE is charged
  43.      for  distribution.  The  QBNews is copyrighted in  full  by  Clearware
  44.      Computing.  The  authors  hold  the  copyright  to  their   individual
  45.      articles.  All program code appearing in QBNews is released  into  the
  46.      public  domain.   You  may  do what you  wish  with  the  code  except
  47.      copyright  it.  QBNews  must  be  distributed  whole  and  unmodified.
  48.      
  49.      You can write The QBNews at:
  50.      
  51.           The QBNews
  52.           P.O. Box 507
  53.           Sandy Hook, CT 06482
  54.      
  55.      Copyright (c) 1990 by Clearware Computing.
  56.      
  57.      The QBNews                                                   Page    i
  58.      Volume  1, Number  4                                September  3, 1990
  59.      
  60.      
  61.      
  62.  
  63.      ----------------------------------------------------------------------
  64.  
  65.                         T A B L E   O F   C O N T E N T S
  66.  
  67.      
  68.      1.  From the Editors Desk
  69.           CONTEST !!!! .................................................  1
  70.  
  71.      2.  Beginners Corner
  72.           The BASICS of QB'S Serial Communications by Ranjit Aiyagari ..  2
  73.  
  74.      3.  Who ya gonna call? CALL INTERRUPT
  75.           Using a FOSSIL - Take 1 by Hector Plasmic ....................  6
  76.           Using a FOSSIL - Take 2  by Chris Wagner .....................  7
  77.  
  78.      4.  Product Announcements
  79.           Index Manager for PDS 7 and Networks ......................... 10
  80.           Don Malin's Cross Reference Program .......................... 11
  81.  
  82.      5.  Power Programming
  83.           Peeking at DOS with P.D.Q. by Ethan Winer .................... 13
  84.           A Pop-Up Communications Program with PDQ by Dave Cleary ...... 18
  85.           A Pop-Up Calculator with Stay-Res by Larry Stone ............. 20
  86.  
  87.      6.  Algorithms
  88.           Improving your IQUEUE by Jim Mack ............................ 23
  89.  
  90.      7.  Input Past End
  91.            Get the QBNews on Disk ...................................... 29
  92.            Contacting the QBNews ....................................... 30
  93.  
  94.      The QBNews                                                   Page   ii
  95.      Volume  1, Number  4                                September  3, 1990
  96.  
  97.  
  98.  
  99.      ----------------------------------------------------------------------
  100.                     F r o m   t h e   E d i t o r s   D e s k
  101.      ----------------------------------------------------------------------
  102.  
  103.      Free software to a lucky QBNews reader!!!
  104.      
  105.           In   order  to  gauge  readership  anmd  distribution   of   this
  106.      newsletter,  I  am holding a contest. One lucky reader  will  get  his
  107.      choice of either Crescent Softwares PDQComm or Don Malin's XREF.  Both
  108.      are  fine packages. A description of XREF is included in this  issue's
  109.      Product  announcement  section. PDQComm is a replacement  library  for
  110.      QuickBASIC's  internal  Comm routines. It was also  written  by  yours
  111.      truely. Originally, it was meant to add communications support to  PDQ
  112.      but  it  also  works fine with QuickBASIC and even has  a  far  string
  113.      version  for  BC7. Contact Crescent Software at  203-438-5300  or  the
  114.      Crescent  Software Support BBS at 203-426-5958 for more info on  these
  115.      or other Crescent products.
  116.      
  117.           Now here are the rules. Send a postcard with your Name,  Address,
  118.      and how you received your copy of the QBNews. I don't care if it is "I
  119.      downloaded it from XYZ bbs" or "I got it from my friend Bill", I would
  120.      just like to know. All entries must be postmarked by November  15,1990
  121.      and  only  1 entry per address will be allowed. This contest  is  void
  122.      where prohibited by law. Winner will be notified and announced in  the
  123.      November issue of the QBNews. Even if you aren't interrested in any of
  124.      the  prizes,  drop  me a postcard anyways. I'd like to  know  if  this
  125.      newsletter is reaching everybody who would want it.
  126.      
  127.           That brings me to another topic regarding mail. It seems that all
  128.      the letters I get are from beginning to intermiediate programmers. The
  129.      QBNews tries to please everybody from beginner to "Power  Programmer",
  130.      but  I don't receive mail from these advanced users. I would  like  to
  131.      hear from you so you can let me know what you think about some of  our
  132.      "advanced"  articles. I know there are "Professional"  QB  programmers
  133.      out there and I would like to hear your views on the subject matter in
  134.      the QBNews also.
  135.      
  136.           This  issue is kind of on the large size due to the  special  TSR
  137.      programs you receive with it. I had to leave some sections out to keep
  138.      the size resonable. If you find that you missed a section not included
  139.      in  this  issue,  let me know. I really would like  to  know  what  my
  140.      readers find interresting and what they don't.
  141.      
  142.           Well, so long for another 3 months. Enjoy.
  143.                Dave Cleary
  144.      
  145.      Send your postcards to:
  146.          The QBNews Reader Contest
  147.           P.O. Box 507
  148.           Sandy Hook, CT 06482
  149.      
  150.      Remember to say how you received your copy.
  151.      
  152.      The QBNews                                                     Page  1
  153.      Volume  1, Number  4                                September  3, 1990
  154.  
  155.  
  156.  
  157.      ----------------------------------------------------------------------
  158.                          B e g i n n e r s   C o r n e r
  159.      ----------------------------------------------------------------------
  160.  
  161.      The BASICS of QB'S Serial Communications by Ranjit Aiyagari
  162.      
  163.           QuickBASIC  has  always  been  recognized  for  having  a  unique
  164.      feature which most other languages (i.e. Pascal, C, Fortran)   lacked:
  165.      full serial communications support built in to the  language.  In this
  166.      article,  I'll  explain BASIC's communications   functions  and,  more
  167.      importantly,  their uses.  If you always  wanted to write a BBS  or  a
  168.      terminal  program in QuickBASIC but  never had the faintest idea  how,
  169.      keep reading.
  170.      
  171.           In  order  to  use the modem (or any other  serial  device)  from
  172.      BASIC, you must first OPEN it, treating it as you would treat a  file.
  173.      The  flexible syntax of the OPEN COM statement is explained   well  in
  174.      Microsoft's manuals, but I'll give a most common syntax  of it:
  175.      
  176.       OPEN "COM1:2400,N,8,1,OP0,DS0" FOR RANDOM AS #FileNumber% LEN=1024
  177.      
  178.           The  above statement, as you can probably gather from its  simple
  179.      syntax,  will  open  communications port number 1  at  a  most  common
  180.      setting of 2400 bps, 8 data bits, 1 stop bit, and no parity.  The  OP0
  181.      and  DS0 parameters signify, respectively, for BASIC not to   wait  at
  182.      all  before  communications  lines become active, and  for   BASIC  to
  183.      ignore  (for  simplicity's  sake)  the DSR  (Data  Set  Ready)   line.
  184.      Lastly, the LEN parameter specifies the length of the  input buffer.
  185.      
  186.           Now that you've opened it, output to the modem is easy.  To  send
  187.      an "AT".. command, just do a PRINT #1, ModemCommand$.  Getting   input
  188.      from the modem, however, can be done in multiple ways:
  189.      
  190.           Character  by  character:  This is a  method  I  prefer,  getting
  191.      characters one at a time and dealing with them.  To get one  character
  192.      from  the  modem, use the INPUT$ function in  the   following  manner:
  193.      Char$  = INPUT$(1, #FileNumber%) [where  FileNumber% is of course  the
  194.      file number under which you opened  the communications port.
  195.      
  196.           Everything  waiting  in the modem buffer: With this  method,  you
  197.      can  store whatever is waiting in the input buffer in a  string,   and
  198.      then   deal  with  the  string  as  you  wish  using  BASIC's   string
  199.      manipulation  functions.   This is done by using  the  LOC   function.
  200.      Normally returning the position of the last byte  read for files,  LOC
  201.      changes  meaning when used with  communications devices.  Instead,  it
  202.      returns  the  number of  characters waiting in the input  buffer.   To
  203.      input  the  modem   input  buffer  to  a  string,  do  the  following:
  204.      ModemInput$  =  INPUT$(LOC(FileNumber%), #FileNumber%).  Now  you  can
  205.      use INSTR  to figure out whether certain characters were returned,  or
  206.      MID$  to extract part of the input.
  207.      
  208.           A  commonly  asked question is "How do I recover from  a  carrier
  209.      drop?"   Since the CD (carrier detect) option in the  OPEN   statement
  210.      
  211.      The QBNews                                                     Page  2
  212.      Volume  1, Number  4                                September  3, 1990
  213.  
  214.      defaults  to  zero,  your program seems to have  no  way  of   knowing
  215.      whether  the other side is connected or not.  The method I   recommend
  216.      for this is using an ON TIMER routine, such as this:
  217.      
  218.         ON TIMER(15) GOSUB CheckCarrier
  219.         ' Remember to compile with /v when using ON TIMER
  220.      
  221.              Now,  we  use a low-level method of checking whether  the  DCD
  222.      (data   carrier  detect)  line  is up or  down.   You  must  know  the
  223.      communications  port base address first, so to figure it out, do   the
  224.      following   (assuming  the  communications  port  is  in  a   variable
  225.      ComPort%):
  226.      
  227.         DEF SEG = &H40
  228.         BaseAddress% = PEEK((ComPort-1)*2) + PEEK((ComPort-1)*2+1)*256
  229.         ' The base address is usually &H3F8 for COM1 and &H2F8 for COM2
  230.      
  231.      Use the INP function:
  232.      
  233.         CheckCarrier:
  234.         IF (INP(BaseAddress+6) AND 128) = 0 Then
  235.            Print "Carrier lost"
  236.            Connected% = 0
  237.         ELSE
  238.            Connected% = -1
  239.         END IF
  240.         RETURN
  241.      
  242.           Another  common  question:  "How do I wait for a  ring  and  then
  243.      answer?"   This  is  far simpler, and uses  the  EOF  function,  which
  244.      returns  false  if  characters are waiting in the  input  buffer  (You
  245.      should  make sure to have the statement CONST False = 0, True  =   NOT
  246.      False at the top of your program).  To wait for the ring:
  247.      
  248.         PRINT #FileNumber%, "ATE0"
  249.         SLEEP 2                           ' Wait for the modem to respond
  250.         Dummy$ = INPUT$(LOC(FileNumber%), #FileNumber%)  ' Discard "OK"
  251.         ModemInput$ = ""
  252.         DO
  253.         IF NOT EOF(FileNumber%) THEN ' Characters are waiting, so get them
  254.            ModemInput$ = ModemInput$ + Input$(1, #FileNumber%)
  255.         END IF
  256.         LOOP UNTIL INKEY$ <> "" OR INSTR(ModemInput$, "RING")
  257.         Dummy$ = INPUT$(LOC(FileNumber%), #FileNumber%)  ' Clear the buffer
  258.         ' Now, to answer:
  259.         PRINT #FileNumber%, "ATA"
  260.      
  261.           Lastly,  probably  the most frequently asked  question  about  QB
  262.      communications:  "How do I change the BPS rate while connected?"  This
  263.      requires  some  low-level  UART  (Universal  Asynchronous    Receiver-
  264.      Transmitter) accessing [the UART is the chip in control  of the serial
  265.      port].   The  best use of this is to read  the  modem's   "CONNECT..."
  266.      message and change the BPS rate accordingly.  It  requires a series of
  267.      
  268.      The QBNews                                                     Page  3
  269.      Volume  1, Number  4                                September  3, 1990
  270.  
  271.      four OUT statements:
  272.      
  273.         FUNCTION JustNumbers%(X$) STATIC
  274.      
  275.         ' Takes a string and returns the numeric value of the numeric
  276.         ' characters inside it.
  277.      
  278.         Temp$ = ""
  279.         FOR CheckString% = 1 TO LEN(X$)
  280.            Char$ = MID$(X$, CheckString%, 1)
  281.            IF INSTR("1234567890", Char$) THEN Temp$ = Temp$ + Char$
  282.         NEXT CheckString%
  283.         IF Temp$ = "" THEN JustNumbers% = -1 ELSE JustNumbers% = VAL(Temp$)
  284.         Temp$ = "": X$ = ""                  ' Empty the strings
  285.      
  286.         END FUNCTION
  287.      
  288.         ' Assume we've just sent the "ATA"
  289.         ModemInput$ = ""
  290.         DO
  291.         IF NOT EOF(FileNumber%) THEN
  292.            ModemInput$ = ModemInput$ + INPUT$(1, #FileNumber%)
  293.         END IF
  294.         Connect% = INSTR(ModemInput$, "CONNECT")
  295.         LOOP UNTIL Connect% AND_
  296.            INSTR(Connect%, ModemInput$, CHR$(13)+CHR$(10))
  297.      
  298.         NewBpsRate% = JustNumbers%(ModemInput$)
  299.         IF NewBpsRate% = -1 THEN NewBpsRate% = 300      ' Just a "CONNECT"
  300.      
  301.         ' Now, change the BPS rate.  Since we already initialized at 2400
  302.         ' don't bother changing it if the other side is also at 2400.
  303.         ' Also, assume the base address is stored in BaseAddress%
  304.         ' (discussed above)
  305.      
  306.         IF NewBpsRate% <> 2400 THEN
  307.         OUT BaseAddress% + 3, (INP(BaseAddress% + 3) OR &H80)' Enable DLAB
  308.         OUT BaseAddress%, (115200 \ NewBpsRate%) MOD &H100     ' Send LSB
  309.         OUT BaseAddress% + 1, (115200 \ NewBpsRate%) \ &H100   ' Send MSB
  310.         OUT BaseAddress% + 3, (INP(BaseAddress% + 3) AND &H7F)'Disable DLAB
  311.         END IF
  312.      
  313.           Now,   for  an  explanation.   The  first  and  the  fourth   OUT
  314.      statements, as you can see, modify the DLAB, the divisor latch  access
  315.      bit.  The reason for this is that when the DLAB is  enabled, the first
  316.      two  registers (BaseAddress% and BaseAddress+1), instead of being  the
  317.      receive  buffer/transmit  holding  and   interrupt  enable  registers,
  318.      change  their  meaning to the low and  high byte of  the  BPS  divisor
  319.      (also  called  the LSB and MSB).  The  BPS divisor  is  calculated  by
  320.      dividing  115200,  the  maximum serial  port speed, by  the  BPS  rate
  321.      desired.  Thus, these four statements  will modify the BPS rate to any
  322.      value  between  1 and 115200.  This  can be useful when  writing  both
  323.      terminal  programs  and BBS's, when  you want your software  to  "fall
  324.      
  325.      The QBNews                                                     Page  4
  326.      Volume  1, Number  4                                September  3, 1990
  327.  
  328.      back",  that  is,  be able to  transmit at any speed  lower  than  the
  329.      highest.
  330.      
  331.           If you need help on any topic dealing with serial  communications
  332.      in QuickBASIC/BASIC PDS, please feel free to send me a message on  the
  333.      echo.  I've written BBS's and terminal programs in QuickBASIC,   along
  334.      with small communications functions in Assembler, and  probably  would
  335.      be able to help you.
  336.      
  337.  
  338.  
  339.  
  340.  
  341.  
  342.  
  343.  
  344.  
  345.  
  346.  
  347.  
  348.  
  349.  
  350.  
  351.  
  352.  
  353.  
  354.  
  355.  
  356.  
  357.  
  358.  
  359.  
  360.  
  361.  
  362.  
  363.  
  364.  
  365.  
  366.  
  367.  
  368.  
  369.  
  370.  
  371.  
  372.  
  373.  
  374.  
  375.  
  376.  
  377.  
  378.  
  379.  
  380.  
  381.      The QBNews                                                     Page  5
  382.      Volume  1, Number  4                                September  3, 1990
  383.  
  384.  
  385.  
  386.      ----------------------------------------------------------------------
  387.         W h o   y a   g o n n a   c a l l ?   C A L L   I N T E R R U P T
  388.      ----------------------------------------------------------------------
  389.  
  390.      Using a FOSSIL - Take 1 by Hector Plasmic
  391.      
  392.        From FOSSIL.DOC (for version 5 FOSSILs):
  393.      
  394.           "FOSSIL  is an acronym for "Fido/Opus/SEAdog  Standard  Interface
  395.      Layer".  To  say that the concept has gained wide  acceptance  in  the
  396.      FidoNet  community  would be an understatement...  There  are  already
  397.      FOSSIL implementations for the Tandy 2000, Heath/Zenith 100, Sanyo 555
  398.      and  other "non-IBM" architectures. With each new 'port' of the  spec,
  399.      the potential of a properly coded FOSSIL application grows!"
  400.      
  401.           QuickBASIC  has some problems with modem  communications.   There
  402.      are ways around most of the problems; patch this, avoid that, use OUT,
  403.      use  a third-party library, etc.  But it can be a pain in the neck  to
  404.      worry about ways around all the flaws in OPEN COM (and, in the case of
  405.      third-party  libraries, expensive).  FOSSIL will not only handle  your
  406.      communications routines with Interrupt-driven buffered modem i/o,  but
  407.      makes  your  programs  a  little more "generic"  than  they  would  be
  408.      otherwise.
  409.      
  410.           FOSSIL  drivers "steal" interrupt 14h (usually the BIOS's  serial
  411.      communications  interrupt) and install themselves instead.  From  that
  412.      point onward, calls to interrupt 14h go through the FOSSIL instead  of
  413.      to the BIOS directly.  The FOSSIL is basically a "BIOS extender" which
  414.      provides many more functions than the usual three or so provided.
  415.      
  416.           While  I won't attempt to cover every aspect of FOSSIL  usage,  I
  417.      thought I'd present a "FOSSIL package" for QB 4.x that you can use  to
  418.      build  your own programs that use the FOSSIL for communications.   The
  419.      subroutines in the file FOSSIL1.BAS assume that you know the baud rate
  420.      and commport number you're dealing with, although the FOSSIL will  use
  421.      the  commport  at whatever baud it's already set at...all  you  really
  422.      need to know is if you're operating local-only or online.
  423.      
  424.           For more information on the FOSSIL, download one and look for the
  425.      enclosed FOSSILV5.ARC inside the archive.  It will contain  FOSSIL.DOC
  426.      and   FOSSIL.CHT.    These  two  documents  should  contain  all   the
  427.      information you need to utilize every aspect of the FOSSIL.  A few  of
  428.      the FOSSIL drivers available are:
  429.      
  430.      X00.SYS   (Ray Gwinn)
  431.      OPUS!COMM (Bob Hartman)
  432.      BNU       (David Nugent)
  433.      
  434.  
  435.  
  436.  
  437.  
  438.  
  439.      The QBNews                                                     Page  6
  440.      Volume  1, Number  4                                September  3, 1990
  441.  
  442.      Using a FOSSIL - Take 2  by Chris Wagner
  443.      
  444.           So  what  is this FOSSIL thing?  Well, FOSSIL is an  acronym  for
  445.      "Fido/Opus/SEAdog Standard Interface Layer".  What the FOSSIL does  is
  446.      bypass  the BIOS communications functions and replaces them with  it's
  447.      own.   By doing this, the programmer can concentrate on  the  software
  448.      without worrying about the hardware as much.
  449.      
  450.           The  FOSSIL  itself  is  installed  by  adding  a  line  in  your
  451.      config.sys  file that includes the FOSSIL device driver as well  as  a
  452.      few  parameters for the FOSSIL such as transmit buffer size or  locked
  453.      baud  rate.   For  more  information  about  the  FOSSIL  itself   and
  454.      installation,  read FOSSIL.DOC and FOSSIL.CHT.  These files come  with
  455.      the FOSSIL device driver which can be found on many public BBS's.   To
  456.      obtain a complete fossil device driver package, look for a file called
  457.      X00____.___.  Underscores are for version and archive type information
  458.      which will vary.
  459.      
  460.           Once  the  FOSSIL is installed, you need to  access  it  somehow.
  461.      That's  where  I  come  in.   The program  that  I  have  included  in
  462.      FOSSIL2.BAS   is  a  terminal  program  that  does  all  it's   serial
  463.      communications via the fossil device driver.  To use this program, you
  464.      must  have  INTERRUPT  in your library, or load QB.LIB  /  QB.QLB  for
  465.      proper operation.
  466.      
  467.           What  advantages  does a FOSSIL give me?  Well, there  are  many.
  468.      You  have the ability to change baud rate WITHOUT closing  the  serial
  469.      channel,  Baud rates up to 38400 directly supported, Status  functions
  470.      like character waiting and  carrier detect available, and the  ability
  471.      to terminate a program WITHOUT dropping DTR.  All of this can be  done
  472.      using REGULAR QuickBASIC programming and no additional  libraries.
  473.      
  474.           In  the included MYFOS.BAS program, I have coded the  program  so
  475.      that  all  of the SUB programs can be put directly into a  library  if
  476.      desired.  This gives the ability to call FOSSIL functions from any  of
  477.      your programs once they are in your library.
  478.      
  479.           You  will  notice  that  many  of  the  SUB  programs  have  many
  480.      parameters that must be given.  I did this so that they can be used in
  481.      any  program from a library.  The DataType Reg is used extensively  in
  482.      the  program,  and is also passed to all of the  SUB  programs.   This
  483.      allows for the INTERRUPT calls that access the FOSSIL.
  484.      
  485.           In the following paragraphs, I will describe the SUB programs and
  486.      their parameters.  Many of these SUB programs are very small, but have
  487.      many parameters that are of great importance.
  488.      
  489.      Parser:   This SUB is a command line parser (divider) that returns  an
  490.              array of parameters that where given on the command line  when
  491.              the  program  was run.  Using parameters, you  can  start  the
  492.              program with special options other than defaults.
  493.      
  494.      AnsiPrint: All that this sub is for is to print data to the screen via
  495.      
  496.      The QBNews                                                     Page  7
  497.      Volume  1, Number  4                                September  3, 1990
  498.  
  499.              the CONS: device allowing for ANSI graphics.
  500.      
  501.      FossilInit: This SUB  activates the fossil.  It must  be called before
  502.              ANY other fossil functions.  This SUB will also  automatically
  503.              raise DTR.
  504.      
  505.      FossilDeInit: This SUB de-activates  the FOSSIL.  It should  be called
  506.              when your program is finished using the fossil and before your
  507.              program terminates.  The state of DTR is not affected by this
  508.              SUB.
  509.      
  510.      SetHandShake:   This  SUB sets up the  handshaking  between  Computer,
  511.              FOSSIL, and remote computer.  There is many ways to use  this,
  512.              but use wisely.  I find that FOSSIL RTS/CTS works best for  my
  513.              applications.   Remember,  in binary file transfers  that  the
  514.              characters  that represent XON/XOFF will be embedded  in  data
  515.              and will cause problems. Therefore, XON/XOFF should be avoided
  516.              sometimes.
  517.      
  518.      SetPortParams.   This  SUB  has many parameters in order  to  make  it
  519.              generic.  It allows you to set the serial port Baud, Bits  per
  520.              word, stop bits, and parity.
  521.      
  522.      SetDTR:   This sub allows you to raise or lower DTR.  This  is  useful
  523.              to hang up a modem to terminate communications.
  524.      
  525.      Transmit:   This SUB is used to send transmit data to the serial  port
  526.              one  character  at a time.  It will return -2 (and  clear  the
  527.              output  buffer)  if the output buffer is filled.  If  this  is
  528.              undesired (automatic clearing of the buffer) it can easily  be
  529.              removed from the SUB.
  530.      
  531.      Receive:   This  sub  is used to get data from the  serial  port   one
  532.              character  at a time.  It will return -1 if there is  no  data
  533.              waiting in the buffer.  If the receive buffer is over-run,  it
  534.              will be automatically cleared and a -2 will be returned.
  535.      
  536.      Status:  This SUB returns the status of the FOSSIL buffers and Carrier
  537.              Detect  signal.  It returns bitmapped data and is   documented
  538.              in the SUB program.
  539.      
  540.      BaudSelect:  This sub is used to change BAUD rate only, but   requires
  541.              all  the parameters such as bits per word, parity,   and  stop
  542.              bits.
  543.      
  544.       To  demonstrate  all of these SUB programs, I made  yet  another  SUB
  545.      program  called  TERMINAL that you can also put in  a   library.   The
  546.      terminal  can be used to call BBS's or whatever as well as upload  and
  547.      download files as long as you have the Zmodem protocol program DSZ  in
  548.      your  path. The commands that the terminal accepts are  documented  by
  549.      remarks in the source code.
  550.      
  551.      [Editor's  Note]
  552.      
  553.      The QBNews                                                     Page  8
  554.      Volume  1, Number  4                                September  3, 1990
  555.  
  556.      Fossil1.bas and Fossil2.bas are included in the file Fossil.zip.
  557.      
  558.      **********************************************************************
  559.      Chris Wagner is system operator of DREAMLINE, Conshococken PA (FidoNet
  560.      Address 1:273/708)  (215) 825-8996. He can be reached there or in care
  561.      of this newsletter.
  562.      **********************************************************************
  563.      
  564.  
  565.  
  566.  
  567.  
  568.  
  569.  
  570.  
  571.  
  572.  
  573.  
  574.  
  575.  
  576.  
  577.  
  578.  
  579.  
  580.  
  581.  
  582.  
  583.  
  584.  
  585.  
  586.  
  587.  
  588.  
  589.  
  590.  
  591.  
  592.  
  593.  
  594.  
  595.  
  596.  
  597.  
  598.  
  599.  
  600.  
  601.  
  602.  
  603.  
  604.  
  605.  
  606.  
  607.  
  608.  
  609.      The QBNews                                                     Page  9
  610.      Volume  1, Number  4                                September  3, 1990
  611.  
  612.  
  613.  
  614.      ----------------------------------------------------------------------
  615.                     P r o d u c t   A n n o u n c e m e n t s
  616.      ----------------------------------------------------------------------
  617.  
  618.      Index Manager for PDS 7 and Networks
  619.      
  620.       INDEX MANAGER ALLOWS QUICKBASIC/PDS 7 NETWORK OPERATION
  621.      
  622.           For years there has been a critical need for a simple, reasonably
  623.      priced way to run QuickBASIC on a network.  This problem has now  been
  624.      solved.  Index  Manager(tm), the popular $59 QuickBASIC B+  Tree  file
  625.      indexing  package,  has  been  enhanced  to  support  Microsoft  BASIC
  626.      Professional Development System 7.0 and network use.
  627.      
  628.           The  PDS  7.0 version provides support for Microsoft's  new  "far
  629.      string" environment which eliminates BASIC's 64K data area limitation.
  630.      The  Index Manager PDS 7.0 version sells for $99 and can be used  with
  631.      either QuickBASIC or PDS 7.0 with no coding changes.
  632.      
  633.           The  Index  Manager  network version sells for  $250  and  allows
  634.      either  QuickBASIC  or  PDS 7.0 to be used on a network  in  the  file
  635.      sharing, record locking mode.
  636.      
  637.      For further information, contact:
  638.      
  639.      CDP  Consultants
  640.      1700 Circo Del Cielo Drive
  641.      El Cajon, CA 92020
  642.      619-440-6482.
  643.      
  644.  
  645.  
  646.  
  647.  
  648.  
  649.  
  650.  
  651.  
  652.  
  653.  
  654.  
  655.  
  656.  
  657.  
  658.  
  659.  
  660.  
  661.  
  662.  
  663.  
  664.  
  665.  
  666.  
  667.      The QBNews                                                     Page 10
  668.      Volume  1, Number  4                                September  3, 1990
  669.  
  670.      Don Malin's Cross Reference Program
  671.      
  672.           Crescent  Software has announced a sophisticated  cross-reference
  673.      program for BASIC programmers.  Unlike other cross-reference utilities
  674.      that  merely list each variable, Crescent's XREF provides a wealth  of
  675.      useful reports that show exactly what is going on in a program.
  676.      
  677.           Highlights   include   a  Call  Tree  report  which   shows   the
  678.      interrelationships  between  all  procedures.   This  report  may   be
  679.      organized   either   alphabetically,  or  logically   (in   order   of
  680.      occurrence).   Further,  line  numbers may be shown  relative  to  the
  681.      beginning  of procedures like the QuickBASIC environment, or  relative
  682.      to  the  beginning of the source file.  XREF also prints  a  Table  of
  683.      Contents for the entire listing, showing the starting page number  for
  684.      each  procedure.  All reports may be sent to a printer, disk file,  or
  685.      browsed and scrolled on-screen.
  686.      
  687.           According to Crescent, XREF is extremely easy to use, relying  on
  688.      pull-down  menus and dialogue boxes for all program operations.   XREF
  689.      reads  the main program's .MAK file, and uses that to examine all  the
  690.      files  that  comprise  an  entire  application  automatically.    This
  691.      includes  modules  that are external to the main  BASIC  program,  and
  692.      $INCLUDE  files.  XREF understands SHARED, COMMON, COMMON SHARED,  DIM
  693.      AS, DEFINT, and all of the other DEF-type statements.  The program  is
  694.      compatible  with all versions of Microsoft BASIC including BASICA  and
  695.      GW-BASIC,  so it is ideal when converting a large program  from  those
  696.      earlier BASIC dialects.
  697.      
  698.           XREF also includes a unique utility to extract all quoted strings
  699.      and  remarks  and write them to file, for proofing  with  any  popular
  700.      spelling checker.  A companion utility will then remerge the corrected
  701.      text  back  into the source file, with the  original  spacing  intact.
  702.      This  feature  also simplifies translating a program  into  a  foreign
  703.      language.
  704.      
  705.           The Object Summary report lists all of the program objects,  such
  706.      as BASIC key words, procedures (SUBs and FUNCTIONs), simple variables,
  707.      TYPE  variables, and both Static and Dynamic arrays.  Program  objects
  708.      are grouped by their type, and displayed alphabetically.  Each  object
  709.      is listed with information about where it was defined, and the  number
  710.      of  times it was used.  Other reports show BASIC key word  usage,  and
  711.      indicate  which  variables  are passed as parameters,  and  which  are
  712.      Static,  Dynamic,  Automatic (local stack variables),  and  which  are
  713.      Shared.
  714.      
  715.           XREF requires any version of Microsoft BASIC; 512K RAM (640K plus
  716.      64K  EMS  recommended  but not mandatory); DOS 2.1  or  later;  and  a
  717.      PC/XT/AT  or  compatible  computer.  Full BASIC  source  is  provided,
  718.      however   Crescent's  QuickPak  Professional  library  is  needed   to
  719.      recompile  the XREF program.  5-1/4 inch disks are standard,  although
  720.      3-1/2 inch disks are available if specified when ordering.  XREF costs
  721.      only   $59.00,  which  includes  free  technical  assistance   and   a
  722.      comprehensive manual with tips and tricks for program optimization.
  723.      
  724.      The QBNews                                                     Page 11
  725.      Volume  1, Number  4                                September  3, 1990
  726.  
  727.      
  728.      Crescent Software
  729.      32 Seventy Acres
  730.      West Redding, CT  06896
  731.      Phone: 203-438-5300  FAX: 203-431-4626  CompuServe: 72657,3070
  732.      
  733.  
  734.  
  735.  
  736.  
  737.  
  738.  
  739.  
  740.  
  741.  
  742.  
  743.  
  744.  
  745.  
  746.  
  747.  
  748.  
  749.  
  750.  
  751.  
  752.  
  753.  
  754.  
  755.  
  756.  
  757.  
  758.  
  759.  
  760.  
  761.  
  762.  
  763.  
  764.  
  765.  
  766.  
  767.  
  768.  
  769.  
  770.  
  771.  
  772.  
  773.  
  774.  
  775.  
  776.  
  777.  
  778.  
  779.  
  780.      The QBNews                                                     Page 12
  781.      Volume  1, Number  4                                September  3, 1990
  782.  
  783.  
  784.  
  785.      ----------------------------------------------------------------------
  786.                         P o w e r   P r o g r a m m i n g
  787.      ----------------------------------------------------------------------
  788.  
  789.      Peeking at DOS with P.D.Q. by Ethan Winer
  790.      
  791.           When  most  programmers  consider writing  a  TSR  program,  they
  792.      immediately think of having to learn C or assembly language.  DOS  was
  793.      never   intended   to   support   multiple   applications    operating
  794.      simultaneously,  and  creating a TSR involves  some  extremely  tricky
  795.      programming.   To answer this need my company, Crescent Software,  has
  796.      developed  an add-on library for use with QuickBASIC and BASIC 7  that
  797.      lets BASIC programmers write several types of TSR programs which  take
  798.      as  little as 3K of memory when resident.  P.D.Q. can also be used  to
  799.      write  non-TSR programs as well, with .EXE file sizes starting at  350
  800.      bytes.   Our purpose here, however, is to examine an  interesting  and
  801.      useful  utility that we provide as a TSR programming example with  the
  802.      product.   A ready to run version of this program is also provided  in
  803.      the file DOSWATCH.EXE.
  804.      
  805.           P.D.Q.  supports  three different ways to create  a  TSR  program
  806.      using  BASIC.  The  first  uses a  "simplified"  method,  whereby  the
  807.      programmer specifies a hot key, and a location in the program that  is
  808.      to  be  executed  each time that key is  pressed.   Once  the  program
  809.      receives control, it may freely open and access disk files, regardless
  810.      of what the underlying application is doing at the time.  Because  DOS
  811.      is  not reentrant, this is normally a very difficult programming  feat
  812.      to  accomplish.   Indeed,  entire books have been  written  about  the
  813.      various complexities of writing TSR programs.  Therefore, much of  the
  814.      appeal of P.D.Q. is that it does all of the hard parts for you through
  815.      the  supplied assembly language routines. An example of this  type  of
  816.      TSR is in the accompanying article for TSRTerm.
  817.      
  818.           The second type of TSR lets you manually trap system  interrupts,
  819.      and with the ease of BASIC accomplish virtually anything that could be
  820.      done in assembly language.  Of course, the programmer must  understand
  821.      how  interrupt  services  are accessed, and I  often  recommend  Peter
  822.      Norton's  excellent  "Programmer's Guide to the IBM PC"  published  by
  823.      Microsoft  Press.   The  third  type  of  TSR  lets  you  combine  the
  824.      flexibility  of  manual  interrupt handling with  the  safety  of  the
  825.      simplified  hot key methods.  In the DOSWATCH program I will  describe
  826.      here  we will manually intercept DOS Interrupt 21h (Hex) to provide  a
  827.      "window" into its inner workings.
  828.      
  829.      
  830.        P.D.Q. TSR INTERRUPT HANDLING SERVICES
  831.      
  832.           There are many routines provided with P.D.Q. to support interrupt
  833.      handling,  and  several of these will be described.   Also,  for  each
  834.      interrupt that a program will be handling, an 18-element TYPE variable
  835.      must  be  defined.   This  TYPE variable is used  to  hold  the  CPU's
  836.      registers,  as well as the address and segment to use if the  original
  837.      interrupt will be accessed.  The Registers TYPE variable is very  much
  838.      
  839.      The QBNews                                                     Page 13
  840.      Volume  1, Number  4                                September  3, 1990
  841.  
  842.      like  the TYPE variable BASIC requires when using CALL  INTERRUPT,  in
  843.      that the various CPU registers may be assigned and examined.   Several
  844.      additional  TYPE  elements  are also defined, which  are  specific  to
  845.      P.D.Q.   For example, the segment and address of the  BASIC  interrupt
  846.      handling code are stored there.
  847.      
  848.           We'll begin by briefly examining the P.D.Q. TSR routines used  in
  849.      DOSWATCH.  The  first is PointIntHere, and it indicates where  in  the
  850.      BASIC program to begin executing when the specified interrupt  occurs.
  851.      Because BASIC does not provide a direct way to obtain the address of a
  852.      particular  statement  or  line,  a  call  to  PointIntHere  must   be
  853.      immediately followed by a GOTO.  The very next program statement  will
  854.      then receive control each time the specified interrupt occurs.
  855.      
  856.           The next two routines are IntEntry1 and IntEntry2, and these must
  857.      be  the very first two statements in the body of the  BASIC  interrupt
  858.      handler  code.   These routines copy the current CPU  register  values
  859.      into  the  TYPE  variable, so they may be examined  and  set  by  your
  860.      program.   (Internally,  IntEntry1 saves the current value of  the  AX
  861.      register and establishes "DGROUP addressability", so variables  within
  862.      the TSR program will be accessed correctly.  IntEntry2 then copies the
  863.      remaining  register  values into the TYPE variable, and jumps  to  the
  864.      correct location in the TSR program.)
  865.      
  866.           IntEntry2 also expects an "Action" parameter, which tells it what
  867.      to do if another interrupt occurs before you have finished  processing
  868.      the  first  one.  There  are two options -- pass  control  on  to  the
  869.      original  interrupt  handler,  or ignore the  interrupt  entirely  and
  870.      simply  return  to the caller.  The only situation in which  a  second
  871.      interrupt  could occur like this is when trapping hardware  interrupts
  872.      such as the timer tick or the keyboard or communications interrupts.
  873.      
  874.           While  a program is processing the interrupt, it may call one  of
  875.      the  three P.D.Q. interrupt service routines.  The first of  these  is
  876.      GotoOldInt,  which passes control to the original  interrupt  handler.
  877.      GotoOldInt  is  used  when  a program  is  intercepting  only  certain
  878.      services,  and the current service is not one of those.  In that  case
  879.      you  would  want to pass control on to the  original  (or  subsequent)
  880.      handler.   For example, if you are intercepting DOS interrupt 21h  and
  881.      care only about, say, service 4Eh, then you would call GotoOldInt  for
  882.      all of the other services so DOS could handle them.
  883.      
  884.           The second routine is CallOldInt, and this routine lets you  call
  885.      the original interrupt as a subroutine, and then receive control again
  886.      when  it  has finished.  This would be useful  when  intercepting  the
  887.      printer  interrupt, for instance, perhaps to test the success  of  the
  888.      last print attempt.
  889.      
  890.           The  final  interrupt handling routine  is  ReturnFromInt,  which
  891.      returns control to the underlying application.  ReturnFromInt would be
  892.      used when your program has processed the interrupt entirely by itself,
  893.      and  no  further action is needed by the  original  handler.   Neither
  894.      CallOldInt  nor  ReturnFromInt  are used by DOSWATCH,  and  these  are
  895.      
  896.      The QBNews                                                     Page 14
  897.      Volume  1, Number  4                                September  3, 1990
  898.  
  899.      described solely for your interest.
  900.      
  901.      
  902.         INSIDE DOSWATCH
  903.      
  904.           The  DOSWATCH program shows how to intercept DOS  Interrupt  21h,
  905.      and  it  also serves as a good example of writing  a  general  purpose
  906.      interrupt  handler  using  P.D.Q.   DOSWATCH is  a  TSR  program  that
  907.      monitors  every  call  made to DOS Interrupt 21h,  and  then  displays
  908.      information  about the current service that is being  requested.   The
  909.      service number is printed in the upper left corner of the screen,  and
  910.      in many cases additional information is also shown. Watching DOS as it
  911.      works  can be very enlightening, and DOSWATCH lets you view  not  only
  912.      the  activity of your application programs, but also DOS itself.   The
  913.      DOSWATCH.BAS source listing is shown in Figure 1.
  914.      
  915.           DOSWATCH  begins by including PDQDECL.BAS, which declares all  of
  916.      the  available  P.D.Q.  extensions  and  defines  the  Registers  TYPE
  917.      variable.  Next, a unique ID string is defined, which in this case  is
  918.      also the sign-on message.  P.D.Q. uses the ID string internally to let
  919.      you  check  for multiple installations. However, that feature  is  not
  920.      exploited here for the sake of simplicity.
  921.      
  922.           Because DOSWATCH may receive control at any time, it is essential
  923.      that  the  regular  BASIC PRINT statement is  not  used.   Unlike  the
  924.      simplified  TSR method which allows nearly any BASIC statement  to  be
  925.      used  freely without regard to the current state of DOS or  the  BIOS,
  926.      DOSWATCH  must use the PDQPrint routine that writes directly to  video
  927.      memory.   PDQPrint is a "quick print" routine, and it expects the  row
  928.      and  column as passed parameters.  Therefore, we must use  CSRLIN  and
  929.      POS(0) to know where that is.  (P.D.Q. does in fact allow TSR programs
  930.      to  perform nearly any service within a manual interrupt handler,  but
  931.      an  additional  call is needed and DOSWATCH doesn't  truly  need  that
  932.      feature.)
  933.      
  934.           The next two statements define the strings that will receive  the
  935.      information message, and the file or directory name when  appropriate.
  936.      The  statements that follow establish several variables that  will  be
  937.      used  by the program. Using variables as parameters is  always  faster
  938.      than constants, because BC.EXE generates extra code to store constants
  939.      in  memory  each time they are used. Likewise,  assigning  Zero$  once
  940.      eliminates repeated references to CHR$() each time INSTR is used later
  941.      on  in  the  program.   This  is true  for  both  P.D.Q.  and  regular
  942.      QuickBASIC.
  943.      
  944.           Although  it may not be obvious, using INSTR(DOSName$, Zero$)  is
  945.      faster  and creates less code than INSTR(DOSName$,  CHR$(0)),  because
  946.      CHR$() is actually a called routine.  A few microseconds either way is
  947.      unlikely  to  matter  in  most programs, but  in  a  TSR  that  steals
  948.      interrupt  processing time, speed is at least as important as  program
  949.      size.  (Defining and assigning Zero$ adds a dozen or so bytes.)
  950.      
  951.           The  last preparatory step is to assign Registers.IntNum  to  the
  952.      
  953.      The QBNews                                                     Page 15
  954.      Volume  1, Number  4                                September  3, 1990
  955.  
  956.      value  &H21,  to specify which interrupt is to be  trapped.   Finally,
  957.      PointIntHere  is  called, followed by a GOTO to the very  end  of  the
  958.      source listing where the program is installed as a TSR by calling  the
  959.      EndTSR routine.
  960.      
  961.           The remaining program statements will now be executed every  time
  962.      an  Interrupt 21h occurs.  The first two steps are calls to  IntEntry1
  963.      and  IntEntry2, and this is mandatory in all TSR programs that do  not
  964.      use  the  simplified method. These routines simply  save  the  current
  965.      processor  registers  values, so they can be  restored  when  DOSWATCH
  966.      passes  control to DOS later on.  The next two steps clear  the  Ticks
  967.      variable, and derive the current service number from the AX  register.
  968.      For  DOS  services  that process a file or  directory  name,  DOSWATCH
  969.      pauses  for  a  half-second allowing time to  read  the  name.   Ticks
  970.      specifies  the number of timer ticks in 18ths of a second.  For  other
  971.      services  only the service number is displayed, and there is no  added
  972.      delay.
  973.      
  974.           Fifteen  different  DOS services are recognized,  and  these  are
  975.      filtered  through a SELECT/CASE block.  All of the supported  services
  976.      assign  Message$  to  the appropriate text, and  those  services  that
  977.      process  a file or directory name also use the GetDOSName  subroutine.
  978.      GetDOSName  copies  the current name into the DOSName$  variable,  and
  979.      also  sets  Ticks  to  8 to allow time to read  it.   In  some  cases,
  980.      additional  information  is  assigned to Message$,  for  example  when
  981.      reporting  a drive letter or file handle number.  This information  is
  982.      taken  from the appropriate registers as necessary.  If  a  particular
  983.      service is not supported, then Message$ is simply cleared to blanks in
  984.      the CASE ELSE code.
  985.      
  986.           Because  DOSWATCH  is  not actually processing  any  of  the  DOS
  987.      services, the final step is to call GotoOldInt, which in turn jumps to
  988.      the internal DOS function dispatcher.  Thus, DOSWATCH displays what is
  989.      about to happen, before DOS actually receives control.
  990.      
  991.           The  remaining  statements comprise  the  GetDOSName  subroutine,
  992.      which  copies  the current file or directory name  into  the  DOSName$
  993.      variable.  In this case, the P.D.Q. BlockCopy routine copies the first
  994.      50  characters  pointed to by DS:DX into DOSName$, and then  INSTR  is
  995.      used  to  locate the CHR$(0) which marks the end of  the  name.   Only
  996.      those  characters  that precede the zero byte are  retained,  and  the
  997.      LEFT$ assignment clears any characters that follow the name.
  998.      
  999.           Running  DOSWATCH  once  will  install  it  as  a  TSR,  and  all
  1000.      subsequent  DOS operations will then be displayed on the top  line  of
  1001.      the  screen.  Observing DOSWATCH as it works can provide much  insight
  1002.      into  DOS' internal operation. For example, you will no doubt find  it
  1003.      enlightening  to start QuickBASIC and load a program such as  DOSWATCH
  1004.      itself.   This shows DOS at work as it loads and executes QB.EXE,  and
  1005.      then  you  can watch QuickBASIC as it loads the main program  and  the
  1006.      PDQDECL.BAS Include file.  Equally interesting is all the  unnecessary
  1007.      DOS  activity QuickBASIC performs to obtain a list of file names  when
  1008.      you select Alt-F-L from the pull-down menu.
  1009.      
  1010.      The QBNews                                                     Page 16
  1011.      Volume  1, Number  4                                September  3, 1990
  1012.  
  1013.      
  1014.           You  could also modify DOSWATCH to pause briefly for all  of  the
  1015.      DOS services rather than just some of them.  Even though the operation
  1016.      of  your PC will be slowed dramatically, many varied  and  interesting
  1017.      facets  of DOS will become apparent.  For example, each time  you  use
  1018.      the  DIR  command, DOS (actually COMMAND.COM) always  changes  to  the
  1019.      current  directory,  opens the directory "file", and then  writes  the
  1020.      directory information to Handle 1.  The added delay will also let  you
  1021.      observe  DOS  as it closes all available handles each time  a  program
  1022.      terminates.
  1023.      
  1024.           As you can see, besides providing an excellent way to learn  more
  1025.      about TSR programming, DOSWATCH is also a very useful utility  program
  1026.      in its own right. One of our primary goals in developing P.D.Q. was to
  1027.      allow BASIC programmers to create programs as small and fast as  those
  1028.      written in C.  With a minimum .EXE file size less than one-fourth that
  1029.      of QuickC and Turbo C, I believe we have met that goal.
  1030.      
  1031.      [Editor's note: P.D.Q. costs $129 plus $6 for 2nd day shipping, and it
  1032.      is available from Crescent Software at the address shown below.]
  1033.      
  1034.      **********************************************************************
  1035.           Ethan Winer is President of Crescent Software, and is the  author
  1036.      of  their  QuickPak Professional and P.D.Q. products.   Ethan  may  be
  1037.      reached at 32 Seventy Acres, West Redding, CT 06896, 203-438-5300;  on
  1038.      CompuServe at 72657,3070; and on MCI Mail as EWINER.
  1039.      **********************************************************************
  1040.      
  1041.  
  1042.  
  1043.  
  1044.  
  1045.  
  1046.  
  1047.  
  1048.  
  1049.  
  1050.  
  1051.  
  1052.  
  1053.  
  1054.  
  1055.  
  1056.  
  1057.  
  1058.  
  1059.  
  1060.  
  1061.  
  1062.  
  1063.  
  1064.  
  1065.  
  1066.      The QBNews                                                     Page 17
  1067.      Volume  1, Number  4                                September  3, 1990
  1068.  
  1069.      A Pop-Up Communications Program with PDQ by Dave Cleary
  1070.      
  1071.           One of the most asked questions I have heard is "How do I make  a
  1072.      QuickBASIC  program a TSR?". That is the reason I chose to  devote  an
  1073.      issue  of  The  QBNews on how to accomplish this.  With  the  help  of
  1074.      Crescent Software's PDQ or Microhelp's Stay-Res Plus, TSR  programming
  1075.      is made easy for QuickBASIC programmers.
  1076.      
  1077.           I  am  going to explain a Pop-Up communications program  that  is
  1078.      included  as a demo with PDQComm. PDQComm adds communications  support
  1079.      to  PDQ  and it also fixes some of the "features" that  Microsoft  has
  1080.      built into QuickBASIC's internal communications support. TSRTerm is  a
  1081.      PDQ  simplified pop-up. It is called simplified because all  the  hard
  1082.      work of making sure your TSR won't crash the system is taken care  for
  1083.      you.
  1084.      
  1085.           The first thing you need to do when creating a simplified PDQ TSR
  1086.      is to create an ID$. PDQ uses this string to determine if the  program
  1087.      is  already  installed  and  also is used  when  the  program  is  de-
  1088.      installed.  It is important that this is your first string  assignment
  1089.      because  QB  dynamically moves strings around as they  get  added  and
  1090.      deleted  and  ID$ can not move. ID$ also has to be  unique.  One  good
  1091.      practice is to use the program's name and version number as the ID.
  1092.      
  1093.           Next you need to specify the hot key. The hot key is stored in  a
  1094.      normal  integer and is specified in two portions. They upper  byte  is
  1095.      the  shift  mask  while the lower byte is the scan code  for  the  key
  1096.      desired. The shift mask lets you select the Alt, Ctrl, Left Shift, and
  1097.      Right  Shift to be used with your hot key. You can also OR the  values
  1098.      of  the  shift mask together to get 3 or 4 key  combinations  such  as
  1099.      Ctrl-Alt-C. I have chosen Alt-C for my hot key. Specifying the hot key
  1100.      in hex with &H makes it easier to work with. &H8 is the shift mask for
  1101.      the alternate key while &H2E is the scan code for the C key.
  1102.      
  1103.           Right after I specify the hot key, I check to see if the  program
  1104.      is  already  installed.  This is done by a call  to  the  TSRInstalled
  1105.      function,   passing  it  your  ID$.  If  the  program  is   installed,
  1106.      TSRInstalled  returns the DGROUP segment where it was found.  This  is
  1107.      used for deinstalling the TSR later in the code. Otherwise it  returns
  1108.      a  0. We then do some port initialization with PDQComm  routines.  You
  1109.      may  notice  that the PDQComm routines mimic QuickBASIC's as  much  as
  1110.      possible.  This was done to make PDQComm easy to integrate  into  your
  1111.      QuickBASIC  program. BTW, PDQComm also works with  regular  QuickBASIC
  1112.      and PDS 7 far strings.
  1113.      
  1114.           Now  comes  the  hard  part of using PDQ.  You  make  a  call  to
  1115.      PopUpHere  with  your  hot  key and ID$. You  must  then  put  a  GOTO
  1116.      immediately after the call to PopUpHere. The GOTO jumps over the  code
  1117.      that  will be executed when it pops up. All you have to do is  make  a
  1118.      call to EndTSR and your program is now resident. Well, that isn't  too
  1119.      hard.  That is what makes PDQ so good. It is very simple to  make  all
  1120.      kinds of TSR's.
  1121.      
  1122.      
  1123.      The QBNews                                                     Page 18
  1124.      Volume  1, Number  4                                September  3, 1990
  1125.  
  1126.           When you invoke the hot key of your TSR, control will be given to
  1127.      your  program right after the GOTO statement. Will you are popped  up,
  1128.      you can use almost any QuickBASIC statement you want without  worrying
  1129.      about crashing your system. The only restrictions you have is the  use
  1130.      of  INPUT and INKEY$. PDQ gives you replacements for  these  routines,
  1131.      BIOSInput   and  BIOSInkey,  so  you  can  easily  get   around   this
  1132.      restriction.
  1133.      
  1134.           Next,  you need to know how to return control to  the  underlying
  1135.      application. This is done with a call to PopDown. PDQ doesn't save and
  1136.      restore screens for you so you need to do it yourself. That is what  I
  1137.      am  doing in the statements preceding the call to PopDown.  I  restore
  1138.      the  cursor position and screen that I had saved when the program  had
  1139.      popped-up.
  1140.      
  1141.           All that leaves now is the PDQ routine used to deinstall your TSR
  1142.      from memory. That code is under the label Deinstall. In this  program,
  1143.      I have chosen to deinstall it by executing it again at the DOS prompt.
  1144.      If  TSRTerm finds itself already installed, it will  deinstall  itself
  1145.      from  memory.  This is done with a call to PopDeinstal  function.  You
  1146.      pass  this  function the segment that was determined by  the  call  to
  1147.      TSRInstalled  and your ID$. It will then tell you if your program  was
  1148.      successfully  deinstalled or not. That is all there is to  programming
  1149.      pop-up  TSRs  with  PDQ. PDQ and PDQComm is  available  from  Crescent
  1150.      Software  for $129 and $49 respectively. You can contact  Crescent  at
  1151.      203-438-5300.
  1152.      
  1153.      **********************************************************************
  1154.      Dave  Cleary  is an electronics engineer and  programmer  for  Vectron
  1155.      Laboratories  in  Norwalk, CT. He is also the author  of  PDQComm  and
  1156.      editor  of  this  newsletter.  He  can be  reached  in  care  of  this
  1157.      newsletter, on Compuserve as 76510,1725, on Prodigy as HSRW18A, or  on
  1158.      the Crescent Software Support BBS 203-426-5958 1:141/777.
  1159.      **********************************************************************
  1160.      
  1161.      [Editor's Note]
  1162.           Since TSRTerm was meant only for demonstration purposes, the baud
  1163.      and dial prefix is hardcoded in. These are 1200 and ATDT respectively.
  1164.      You  will  need to recompile and link with PDQ and PDQComm  to  change
  1165.      these. All files are located in TERM.ZIP.
  1166.      
  1167.  
  1168.  
  1169.  
  1170.  
  1171.  
  1172.  
  1173.  
  1174.  
  1175.  
  1176.  
  1177.  
  1178.  
  1179.      The QBNews                                                     Page 19
  1180.      Volume  1, Number  4                                September  3, 1990
  1181.  
  1182.      Using Stay-Res Plus to make TSR's by Larry Stone
  1183.      
  1184.           Have  you  ever  had  the need to create a  program  that  is RAM
  1185.      resident?   Needless  to  say, it is impossible to do it  directly  in
  1186.      BASIC because of the controlling influence of the BASIC engine.   This
  1187.      doesn't  mean  that it can't be done, it means that it can't  be  done
  1188.      directly.   There are two commercial products available that can allow
  1189.      your QB programs to become RAM resident.   One product, PDQ is offered
  1190.      by Crescent Software and the other, Stay-Res Plus by  MicroHelp,  Inc.
  1191.      I own both products and highly recommend each.
  1192.      
  1193.           I  use PDQ for small,  memory resident utilities - those programs
  1194.      whose DOS kernels are no larger than 15K bytes.   But, most of what  I
  1195.      code  turns out to be full-fledged application programs.    Not little
  1196.      utilities performing a single minded task, rather, my programs tend to
  1197.      be  large  applications that have multiple menus and perform  multiple
  1198.      I/O functions.  Stay-Res Plus excels in this arena.
  1199.      
  1200.           Stay-Res Plus,  coupled with a little additional effort  by  you,
  1201.      can  turn  your application into a TSR  (Terminate and Stay Resident).
  1202.      A  Stay-Res Plus assisted application can pop-up with the press of  up
  1203.      to 23 pre-defined hot keys, on a specific date and time, on the  "ring
  1204.      detect" from a communications port, or even from a POKE by your  other
  1205.      programs.   Your  Stay-Res  program can even SHELL other  applications
  1206.      if popped-up over DOS.  And, most important, when your program goes to
  1207.      sleep, it only locks out a 10K - 11K byte DOS kernel, sending the rest
  1208.      of the memory "image" to either EMS, or to temporary disk files  (note
  1209.      Stay-Res will allow the entire application to be DOS RAM resident).
  1210.      
  1211.           To write a Stay-Res application demands of you to conform to some
  1212.      basic (no pun intended) rules.   Your program needs an  initialization
  1213.      section  where all of your arrays and TYPEs are DIMed, and CONST's are
  1214.      defined,  and  where all of the necessary logic required is  performed
  1215.      before entering the main program section.   Here is where your program
  1216.      displays  it's message that it is going to sleep.   Your program  also
  1217.      needs  a memory-resident section which the main section will  transfer
  1218.      control to, every time it pops down.
  1219.      
  1220.           Because your program will be TSR, there are a few do's and don'ts
  1221.      you must adhere to.  Never, ever ERASE or REDIM an array.  This is due
  1222.      to how BASIC will handle these commands.   Issuing these commands will
  1223.      allow BASIC to move memory around.  Once this happens, Stay-Res cannot
  1224.      protect the memory pool and your program will probably crash.   If you
  1225.      need to clear a numeric array, place it into a FOR...NEXT loop and set
  1226.      each element of the array to zero.  String arrays would be set to null
  1227.      
  1228.           Dynamic arrays also need special attention due to the manner that
  1229.      BASIC allocates their memory.  QB4, BASCOM6, or PDS will store dynamic
  1230.      arrays downward from the top of the heap (high memory) instead of just
  1231.      above  the stack (bottom of the heap), leaving a gap in  between.   In
  1232.      order for Stay-Res to protect this memory, you must instruct QB to put
  1233.      these  arrays just above the stack, making all of the program's memory
  1234.      contiguous.  You do this by using BASIC's SETMEM instruction  followed
  1235.      
  1236.      The QBNews                                                     Page 20
  1237.      Volume  1, Number  4                                September  3, 1990
  1238.  
  1239.      by a call to SrAutoSetBlock.   A note for all of those Stay-Res  users
  1240.      who may be reading this.   Stay-Res v3.3 has an undocumented  command,
  1241.      SrAutoSetBlock.  This command can be used in lieu of SrSetBlock and is
  1242.      much more efficient.  Simply DIM and define every variable possible at
  1243.      the top of your code (pretend your programming in Pascal), then  issue
  1244.      the command HeapMem& = FRE(-1).  Subtract a fudge factor from HeapMem&
  1245.      to account for anything missed or for what variable length strings may
  1246.      require:  HeapMem& = HeapMem& - 2048  then have BASIC set  the  memory
  1247.      contiguous: MemNeeded& = SETMEM(-HeapMem&) and follow up with the call
  1248.      CALL SrAutoSetBlock(Paragraphs%, Ecode%).  Then you should check if it
  1249.      will  work with:   IF MemNeeded& <= HeapMem& OR Ecode% <> 0 THEN PRINT
  1250.      "Not Enough Memory - Bye Bye".
  1251.      
  1252.           One important question to consider is which BASIC commands cannot
  1253.      be used with Stay-Res.   Well, under no circumstance can you ever  use
  1254.      BEEP  or  PRINT CHR$(7), or BASIC's RUN or SHELL  statements once your
  1255.      program has become memory resident the first time (use the alternative
  1256.      SHELL's  supplied with Stay-Res).   You can use SOUND or PLAY so  long
  1257.      as you allow sufficient time for the speaker to shut off before  going
  1258.      to sleep.  However, when Stay-Res pops up with an Ecode%  equal  to  1
  1259.      then DOS is, at this time, busy and you cannot use LOCK, UNLOCK, DATE$
  1260.      TIME$, PEN, LOF(), EOF(), PLAY, LPRINT, RANDOMIZE TIMER, and all other
  1261.      file related  commands except LOC(), and all directory commands.   So,
  1262.      what  does this mean?   The manual trys explain it with an example  to
  1263.      instruct  DOS to copy a *huge* file then pop-up your Stay Res  program
  1264.      in the middle of the COPY.  I tried that and, on my system, DOS simply
  1265.      suspended the COPY.  Stay-Res did not pop-up with Ecode = 1 and,  when
  1266.      my program popped down, DOS continued as if it were never interrupted.
  1267.      I  even  tried this procedure with PKzip and it too  simply  suspended
  1268.      it's operation until I popped down.  I suspect that on my computer, it
  1269.      would  have to be networked with local I/O activity before an Ecode of
  1270.      1 would be returned by Stay-Res.   Never-the-less, if DOS is busy, set
  1271.      a  flag  and  if  the user needs any of the commands listed,  print  a
  1272.      message to try later when DOS isn't so busy.
  1273.      
  1274.           Compiling and linking Stay-Res must be done from the DOS  command
  1275.      line.  Compiled programs must use the /O switch and the linker must be
  1276.      instructed to place the Stay-Res object first and a supporting  object
  1277.      last.  The link command should look like:
  1278.      
  1279.              LINK STAYQB4+prog+otherMods+MHMISCP,prog,nul,externalLibs;
  1280.      
  1281.      The term, prog stands for the name of your program.   Notice that prog
  1282.      is repeated mid-way in the command and separated by commas.  This will
  1283.      instruct the linker to name the completed EXE with your program  name.
  1284.      
  1285.           To  facilitate  your coding TSR's, MicroHelp supplies a  template
  1286.      program with clear, concise, pre-defined areas and GOSUB  instructions
  1287.      required.  If you can paint by numbers then you can use this template.
  1288.      Creating a TSR is not a snap but, neither is it very difficult if  you
  1289.      adhere to the rules.
  1290.      
  1291.           To illustrate the power of Stay-Res, accompanying this article is
  1292.      
  1293.      The QBNews                                                     Page 21
  1294.      Volume  1, Number  4                                September  3, 1990
  1295.  
  1296.      a  full function, scientific and statistical calculator with  built-in
  1297.      mouse support.   The calculator has 72 buttons supporting 92 functions
  1298.      such as,  trigometric computations (including inverse and hyperbolic),
  1299.      log e, log 10, and log n, angular conversions, binary, octal,  complex
  1300.      and  hexidecimal number support, a 500 element array  for  statistical
  1301.      computations,  permutations,  combinations,  four types or means,  nth
  1302.      roots, standard deviations, a 512 line user configurable look up table
  1303.      and, not-to-mention, factorials and random number table whose sequence
  1304.      far exceeds BASIC's and offers three types of random number  - defined
  1305.      range randoms, randoms with an exponential curve defined by your mean,
  1306.      and randoms with a normal curve defined by your mean and your standard
  1307.      deviation.   The EXE size is 129,440 bytes and requires  some  204,000
  1308.      bytes  to load.   The program incorporates ERROR trapping  in  several
  1309.      subprograms and functions.  However, when it pops down, it reduces it-
  1310.      self to a 10 Kbyte kernel!!!
  1311.      
  1312.           I and my beta testers found the calculator to be 100%  compatible
  1313.      with QB, QBX, Lotus 123 v2.1, MS WORD, Word Perfect, Qedit,  PC-Write,
  1314.      dClip, CLIPPER applications, dBase, LIST, et. al.   In fact,  the only
  1315.      program  that it won't pop up over is Code View or Lotus v1.1  because
  1316.      these  are  not "well-behaved" programs  (Microsoft  broke  their  own
  1317.      compatibility  requirements when they constructed  Code View).   If  a
  1318.      Stay-Res program is not compatible with another program,  I assure you
  1319.      the fault is that the other program is not well-behaved.
  1320.      
  1321.      **********************************************************************
  1322.           Larry  Stone is President of LSRGroup and is involved in  writing
  1323.      software  for  marine  and  aquatic research. He  can  be  reached  at
  1324.      LSRGroup,  P.O.  Box 5715, Charleston, OR 97420, or in  care  of  this
  1325.      newsletter.
  1326.      **********************************************************************
  1327.      
  1328.      [Editor's Note]
  1329.           When I asked Larry to do a pop up calculator, I expected a small
  1330.      4 function little program. Well, Larry isn't known for a lack of
  1331.      effort and has come up with a truely professional program. Because of
  1332.      the time and effort that has gone into the program, I feel that it is
  1333.      only right for him to offer it as shareware. But, as readers of the
  1334.      QBNews, you also get a special bonus when you register. Just mention
  1335.      that you read the QBNews and Larry will send you full source code when
  1336.      you register. The file CALC.ZIP contains an abridge version of the
  1337.      documentation. To get the full documentation, you can download it from
  1338.      these fine boards:
  1339.      
  1340.      The Crescent Software Support BBS 203-426-5958 2400 Baud
  1341.      The Empire Builder 503-888-4121 2400 Baud
  1342.      
  1343.  
  1344.  
  1345.  
  1346.  
  1347.  
  1348.  
  1349.      The QBNews                                                     Page 22
  1350.      Volume  1, Number  4                                September  3, 1990
  1351.  
  1352.  
  1353.  
  1354.      ----------------------------------------------------------------------
  1355.                                A l g o r i t h m s
  1356.      ----------------------------------------------------------------------
  1357.  
  1358.      Improving your IQUEUE by Jim Mack
  1359.      
  1360.           With all that's been added to the BASIC language in the past  few
  1361.      years,  it  might  be hard to believe that  there's  a  more-or-  less
  1362.      elementary data structure that's been ignored.  Actually, "ignored" is
  1363.      a bit strong, since you can build this structure out of more primitive
  1364.      elements using the core language, but I'll bet most of you never have.
  1365.      
  1366.           You've  probably  gathered from the title that what  I'm  talking
  1367.      about  is  a data stack.  Now, whether a stack is  an  essential  data
  1368.      structure  is  certainly  debatable:  after  all,  aren't   high-level
  1369.      languages  supposed to insulate you from such machine-like  things  as
  1370.      registers and stacks?   And haven't you gotten along for years without
  1371.      a queue?
  1372.      
  1373.           If  you've  never  programmed in MASM (or Forth),  you  might  be
  1374.      blissfully  unaware  of  the  possibilities  of  just  "pushing"  data
  1375.      somewhere and later "popping" it back... and of the concept of feeding
  1376.      data to another process faster than it can be absorbed.
  1377.      
  1378.           Well, you're in for a not-too-rude awakening here, as we  explore
  1379.      the  world  of  buffered  data.  We'll discover  two  useful  sets  of
  1380.      routines  and see how you might apply them to some common  programming
  1381.      tasks.
  1382.      
  1383.           "Queue".   The word is so weird-looking, let's get it out of  the
  1384.      way  first.   Pronounced  "Q" (then why are all  those  other  letters
  1385.      there?),  it's  just  another  word for a "line"  such  as  you  might
  1386.      encounter at a theater or bank.  We used to say as children "it  forms
  1387.      at  the  end"...  not strictly true, but  close  enough.   People  (or
  1388.      objects)  are  "handled" in the same order that they  join  the  line:
  1389.      first  come, first served.  Another common way of saying this is  FIFO
  1390.      (arf!) or first-in, first-out.
  1391.      
  1392.           If there's room in a theater lobby for 20 people to wait in  line
  1393.      ("on"  line  for you New Yorkers), then we can think of the  lobby  as
  1394.      buffering  20 items.  When the lobby is full, no one may  enter  until
  1395.      someone leaves at the head.
  1396.      
  1397.           It's  the same for data.  If one process generates data items  at
  1398.      roughly the same rate that another process uses them, but with  bursts
  1399.      of  activity followed by periods of calm, a buffer can smooth out  the
  1400.      peaks.   The originating process can place items into a queue as  fast
  1401.      as it likes, while the receiving process can take time to work with an
  1402.      item, and get a new one as it requires.
  1403.      
  1404.           A  good  example  of this activity is  QB's  RS-232  serial  COM.
  1405.      Characters  arriving at the port interrupt normal processing  and  are
  1406.      quickly  placed into a queue.  As your program becomes aware of  them,
  1407.      
  1408.      The QBNews                                                     Page 23
  1409.      Volume  1, Number  4                                September  3, 1990
  1410.  
  1411.      it  retrieves characters and, well, does what it does with  them.   If
  1412.      your  program empties the bucket roughly as fast as it's  filling  up,
  1413.      then  the queue provides some leeway for those characters which  might
  1414.      need a little more processing.  The larger the buffer, the  "spongier"
  1415.      the process can be.
  1416.      
  1417.           There are two ways of handling buffered data.  One way is to  let
  1418.      the  buffer fill up, then disallow any more input until  it's  emptied
  1419.      again.  A movie theater functions like that: if you don't get in at 6,
  1420.      you wait until 8... and nobody goes in at 8 until the 6 o'clock  crowd
  1421.      has left.
  1422.      
  1423.           Far more useful for data is the "circular" queue, often called  a
  1424.      ring  buffer  (note to jewelers: I know this isn't what *you*  call  a
  1425.      ring buffer.  Don't write).
  1426.      
  1427.           There are analogies for both in the real world.  The theater line
  1428.      is a straight queue.  A service department might instead use a "take a
  1429.      number"  scheme with tickets numbered from 1 to 100.  Once number  100
  1430.      is serviced, number 1 is next, and so on.
  1431.      
  1432.           "Take  a  number" also introduces the idea of a  pointer.   In  a
  1433.      theater,  the entire line moves forward whenever someone  leaves  from
  1434.      the  head.   In the service department, folks may  move  around  until
  1435.      their number comes up.
  1436.      
  1437.           In  data  terms, the "theater" method  is  terribly  inefficient.
  1438.      Instead,  we use pointers to indicate where the current head and  tail
  1439.      of the queue are.  With pointers, the size of the queue doesn't affect
  1440.      the  speed of operations, so enqueueing and dequeueing data items  can
  1441.      be very fast.
  1442.      
  1443.           We  turn  an  ordinary queue into a circular one  by  the  simple
  1444.      action  of  "wrapping" the pointers, or in more  technical  terms,  by
  1445.      incrementing them MOD the length of the queue... 99 + 1 = 100, but 100
  1446.      + 1 = 1.
  1447.      
  1448.           A queue has two pointers.  The "write" pointer indicates where in
  1449.      the buffer any new item will be stored.  The "read" pointer gives  the
  1450.      location  from  which the oldest item will be  retrieved.   These  are
  1451.      circular  if they're wrapped around when about to point off  the  end.
  1452.      The queue is full if incrementing the write pointer would cause it  to
  1453.      equal the read pointer.
  1454.      
  1455.           So now, at least in concept, you know all about the queue.   It's
  1456.      a form of buffer, a FIFO stack.  It's really that simple... but not as
  1457.      simple as the LIFO (last-in, first-out) stack.
  1458.      
  1459.           To  review what a LIFO stack is, we move from the theater to  the
  1460.      restaurant (almost like real life, isn't it?).  Norton's First Law  of
  1461.      Computer  Explication states, in part, that "...every treatise on  The
  1462.      Stack will begin by discussing dinner plates...", so here we go.
  1463.      
  1464.      
  1465.      The QBNews                                                     Page 24
  1466.      Volume  1, Number  4                                September  3, 1990
  1467.  
  1468.           Ever  eaten  in a cafeteria?  Sure you have.   Then  you've  seen
  1469.      those  "plate-o-matic"  devices  that, when you take  the  top  plate,
  1470.      another  one  springs  up behind it...?  Let's  perform  what  nuclear
  1471.      theorists call a "thought experiment".  How do plates get there in the
  1472.      first  place?   Do you suppose the cafeteria, having  studied  queues,
  1473.      replaces them at the bottom as they're taken off the top?
  1474.      
  1475.           Right.   They operate on a last-washed first-dirtied basis,  just
  1476.      like  the stack we think of in CPU terms.  Items are "pushed"  onto  a
  1477.      LIFO stack, and later "popped" back off.  Technically, a FIFO queue is
  1478.      a  stack  too, but we usually reserve the word "stack"  for  the  LIFO
  1479.      version.
  1480.      
  1481.           A LIFO stack can be managed with only one pointer: where the next
  1482.      pushed item will go or from where the next popped item will come.  You
  1483.      could shuffle all the data each time you push or pop a data item,  but
  1484.      as we saw with queues, a pointer is a lot more efficient.
  1485.      
  1486.           So, a stack is a temporary holding area for data.  It can be used
  1487.      for other things, but that pretty much sums it up.
  1488.      
  1489.           It's tough to come up with any other real-world example of a LIFO
  1490.      stack.   Fortunately  most of us are already familiar  with  the  idea
  1491.      because nearly every computer operation involves some use of the CPU's
  1492.      system stack.
  1493.      
  1494.           But while we realize how vital a stack is for the CPU, what  does
  1495.      it  buy us at the program level to have our own stack?  After all,  in
  1496.      QB if we need somewhere to put an item aside temporarily, why, we just
  1497.      reference  a  new variable... it might even be created on  the  system
  1498.      stack, and we'd never need to know.
  1499.      
  1500.           Well, there are times when an algorithm runs more smoothly, or is
  1501.      easier  to  implement,  using  a stack.  Too, you  may  not  want  the
  1502.      overhead  of another temporary variable (or ten), or may not  want  to
  1503.      dream  up  Yet Another Unique Variable Name.  If so, the  stack's  the
  1504.      ticket.   A  data stack can also allow you to perform  some  recursive
  1505.      operations within an otherwise STATIC procedure.
  1506.      
  1507.           One example of a technique well suited to a stack is Help.   I've
  1508.      written  a  "hyper-help" utility, wherein the user  can  follow  links
  1509.      embedded  in the text to jump from one topic (page) to another in  any
  1510.      sequence  that pleases her.  Keeping track of the path being  followed
  1511.      so  we  can  unwind to any point (and branch  again  from  there),  is
  1512.      potentially  a  nightmare.   But  with a stack  the  job  is  trivial:
  1513.      whenever  she  negotiates a link, we just push the  current  location.
  1514.      When she wishes to back up, we pop page locations back off the  stack.
  1515.      Simple, direct, and obvious.
  1516.      
  1517.           A queue can find use in passing a variable number of arguments to
  1518.      a procedure, something QB can't do on its own.  Put as many items into
  1519.      the queue as you like... the called procedure just pops them out until
  1520.      there  are  no  more.  Queues find their best  use  with  asynchronous
  1521.      
  1522.      The QBNews                                                     Page 25
  1523.      Volume  1, Number  4                                September  3, 1990
  1524.  
  1525.      processes, for example when passing data from an interrupt handler  to
  1526.      a program, or vice versa.
  1527.      
  1528.           Now for the details.  I've written this so there's one stack  and
  1529.      one  queue, each 255 items long.  The code for them is  in  IQUEUE.ASM
  1530.      and ISTACK.ASM, two small MASM files which define several new QB  SUBs
  1531.      and FUNCTIONs, and which reserve the space for the buffers.
  1532.      
  1533.           There's nothing to stop you from using more than one of each, but
  1534.      you'll have to extend the concept on your own.  Once you've had a look
  1535.      at the MASM code, you'll see just how simple all this really is.
  1536.      
  1537.           There  are three nice things about doing it in MASM.   First,  it
  1538.      takes  up no precious DGROUP data space (well, 6 bytes  for  pointers,
  1539.      but  who's counting?).  The reason we don't need any DGROUP space  for
  1540.      the buffers is that we put them into the code segments we declare  for
  1541.      the procedures.
  1542.      
  1543.           Second,  everything about these is automatically global to  every
  1544.      procedure in any module which DECLAREs them.  This applies to  linked-
  1545.      in libraries, run-time libs... anything which "knows" about these  can
  1546.      share  the  procedures  and the data without resorting  to  COMMON  or
  1547.      SHARED declarations.
  1548.      
  1549.           Third  and  most important, it "encapsulates" the queue  and  the
  1550.      stack,  so  you  can  tell  everyone  you're  using   "object-oriented
  1551.      techniques" in your programming.  Of course I'm joking, right?   Well,
  1552.      only a little...
  1553.      
  1554.      Here are the DECLAREs you'll need to include.  For IQUEUE:
  1555.      
  1556.      DECLARE SUB      IQflush ()
  1557.      DECLARE SUB      IQput (intvalue%)
  1558.      DECLARE FUNCTION IQget% ()
  1559.      DECLARE FUNCTION IQfree% ()
  1560.      DECLARE FUNCTION IQavail% ()
  1561.      
  1562.      
  1563.      DECLARE SUB      ISclear ()
  1564.      DECLARE SUB      ISpush (intvalue%)
  1565.      DECLARE FUNCTION ISpop% ()
  1566.      DECLARE FUNCTION ISfree% ()
  1567.      DECLARE FUNCTION ISavail% ()
  1568.      
  1569.           You  can  use  these for integers or  characters.   The  listings
  1570.      include  versions for long integers as well.  Naturally, you  can  use
  1571.      the  long-integer version for smaller objects too, but you'll have  to
  1572.      explicitly convert from integer to long, etc, to do that.
  1573.      
  1574.           If  you  don't like these names, or if they conflict  with  names
  1575.      you're  already using, you can use ALIAS to rename them without  going
  1576.      to the bother of editing and reassembling the MASM code. For example:
  1577.      
  1578.      
  1579.      The QBNews                                                     Page 26
  1580.      Volume  1, Number  4                                September  3, 1990
  1581.  
  1582.      DECLARE SUB PushError ALIAS "ISPush" (intval%)
  1583.      
  1584.           You can then use PushError instead of ISPush to refer to the same
  1585.      routine.
  1586.      
  1587.           So  let's see how these work in QB.  The IQFlush  procedure  does
  1588.      what its name implies: it empties the queue of all data.   For  speed,
  1589.      all  it really does is reset the pointers, since the contents  of  the
  1590.      queue  don't matter if the pointers say it's empty.  So to start  from
  1591.      scratch at any time, just say:
  1592.      
  1593.      IQFlush
  1594.      
  1595.      To place an element into the queue is just as easy:
  1596.      
  1597.      IQPut AnyInteger%
  1598.      IQPut ComplexType.IntArray(elno)
  1599.      IQPut SADD(j$)
  1600.      IQPut (((1000 * 2) \ 3) + 7) ^ 2
  1601.      
  1602.           Anything which evaluates to an integer can be put into the queue,
  1603.      but  watch it... if the queue is full when you try to PUT an  element,
  1604.      you'll generate an Overflow Error in QB.  If this might be a  problem,
  1605.      use the IQFree function:
  1606.      
  1607.      IF IQFree THEN       'meaning "if there's any room"
  1608.           IQPut MyElement%
  1609.      END IF
  1610.      
  1611.           Note that the reason you get an Overflow Error is because  that's
  1612.      the way I designed it: if you want the code to whistle "Lara's  Theme"
  1613.      or  format your hard disk, you can replace my very minimal QUERR  with
  1614.      your own error handler.  Overflow is an easy error to generate, and it
  1615.      does more or less correspond with this condition.
  1616.      
  1617.           To retrieve an element from the queue, use IQGet.  You can  treat
  1618.      IQGet just as though it were a simple integer:
  1619.      
  1620.      PRINT IQGet
  1621.      k = IQGet MOD 3
  1622.      CALL MySub(r$, hpos%, IQGet%)
  1623.      
  1624.      
  1625.           But  as  with  PUT, if you try to GET when the  queue  is  empty,
  1626.      you'll get an Overflow.  To guard against that, use IQAvail:
  1627.      
  1628.      IF IQAvail THEN       'meaning "if anything's there"
  1629.           k = IQGet + 19
  1630.      END IF
  1631.      
  1632.           And  that's it.  The STACK routines are exactly analogous to  the
  1633.      QUEUE routines, so there's no need to review them separately. The MASM
  1634.      listings  are commented well enough that if you need to  modify  them,
  1635.      
  1636.      The QBNews                                                     Page 27
  1637.      Volume  1, Number  4                                September  3, 1990
  1638.  
  1639.      you  can.   You'll  need  MASM 5.1 to reassemble  these  if  you  make
  1640.      changes.
  1641.      
  1642.           Two notes: to make underflow and overflow detection easier in the
  1643.      IQUEUE procedures, the actual number of elements you can store at once
  1644.      is  one less than the EQU'd size of the queue.  And if you  intend  to
  1645.      use  the  queue with interrupts, you'll want to surround  any  pointer
  1646.      operations  with  CLI/STI  to avoid collisions. If you  run  into  any
  1647.      problems, you can reach me via CompuServe at 76630,2012, or on BIX  as
  1648.      "jsmack".  Your comments are always  welcome.
  1649.      
  1650.      **********************************************************************
  1651.      Jim  Mack  is a programmer specializing in real-time systems  for  the
  1652.      entertainment  industry.  He can be reached via CIS ID  76630,2012  on
  1653.      the MSSYS forum in the BASIC or MASM sections, or at Editing  Services
  1654.      Co., PO Box 599, Plymouth MI 48170, (313) 459-4618
  1655.      **********************************************************************
  1656.      
  1657.      [EDITOR'S NOTE]
  1658.      
  1659.           You can find the ASM source and assembled .OBJ's for this article
  1660.      in the file IQUEUE.ZIP.
  1661.      
  1662.  
  1663.  
  1664.  
  1665.  
  1666.  
  1667.  
  1668.  
  1669.  
  1670.  
  1671.  
  1672.  
  1673.  
  1674.  
  1675.  
  1676.  
  1677.  
  1678.  
  1679.  
  1680.  
  1681.  
  1682.  
  1683.  
  1684.  
  1685.  
  1686.  
  1687.  
  1688.  
  1689.  
  1690.  
  1691.  
  1692.      The QBNews                                                     Page 28
  1693.      Volume  1, Number  4                                September  3, 1990
  1694.  
  1695.  
  1696.  
  1697.      ----------------------------------------------------------------------
  1698.                            I n p u t   P a s t   E n d
  1699.      ----------------------------------------------------------------------
  1700.  
  1701.      Due to demand, you can now get the QBNews mailed to you on disk for  a
  1702.      nominal charge. The rates are as follows:
  1703.      
  1704.      United States                $3.00
  1705.      
  1706.      North America (outside US)   $4.00
  1707.      
  1708.      Outside US                   $6.00
  1709.      
  1710.      Please  add $1.00 if you want it on 3.5" media. Also, you can  receive
  1711.      it  in either ZIP, PAK, or LHZ format. If you don't specify, you  will
  1712.      receive it in ZIP format.
  1713.      
  1714.      The first time you request the QBNews, you will receive all  available
  1715.      issues. That way you won't miss any.
  1716.      
  1717.      And  of course, you can always download it free from Treasure  Island.
  1718.      First time callers are granted limited download privlidges so you  can
  1719.      get it. Treasure Island is 9600 HST, is at FIDO address 1:141/730, and
  1720.      its phone is 203-791-8532. To request your copy on disk, send US funds
  1721.      to:
  1722.      
  1723.      The QBNews
  1724.      P.O. Box 507
  1725.      Sandy Hook, CT 06482
  1726.      
  1727.      Remember to specify which archive format you want.
  1728.      
  1729.  
  1730.  
  1731.  
  1732.  
  1733.  
  1734.  
  1735.  
  1736.  
  1737.  
  1738.  
  1739.  
  1740.  
  1741.  
  1742.  
  1743.  
  1744.  
  1745.  
  1746.  
  1747.  
  1748.  
  1749.  
  1750.      The QBNews                                                     Page 29
  1751.      Volume  1, Number  4                                September  3, 1990
  1752.  
  1753.      WE NEED AUTHORS!
  1754.      
  1755.           If you are interested in writing for the QBNews, you can  contact
  1756.      me  at  the  address below. I can also be  reached  on  Compuserve  as
  1757.      76510,1725  or  on  Prodigy as HSRW18A. I am also  the  Sysop  of  the
  1758.      Crescent  Software  Support BBS, 203-426-5958 1:141/770, so I  can  be
  1759.      reached there also. If you are submitting articles, Iask that they  be
  1760.      ASCII text with no more than 70 characters per  line.
  1761.      
  1762.      
  1763.      You can write me at:
  1764.      
  1765.           The QBNews
  1766.           P.O. Box 507
  1767.           Sandy Hook, CT 06482
  1768.      
  1769.      David Cleary
  1770.      
  1771.  
  1772.  
  1773.  
  1774.  
  1775.  
  1776.  
  1777.  
  1778.  
  1779.  
  1780.  
  1781.  
  1782.  
  1783.  
  1784.  
  1785.  
  1786.  
  1787.  
  1788.  
  1789.  
  1790.  
  1791.  
  1792.  
  1793.  
  1794.  
  1795.  
  1796.  
  1797.  
  1798.  
  1799.  
  1800.  
  1801.  
  1802.  
  1803.  
  1804.  
  1805.  
  1806.      The QBNews                                                     Page 30
  1807.  
  1808.